﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data;
using System.Windows.Forms;

namespace MakeIT_Bill_Maker
{
    public class Calculation
    {
        private static Database.DatabaseConnection conn = new Database.DatabaseConnection();

        /// <summary>
        /// Get Service Charge 
        /// </summary>
        /// <returns></returns>
        //public static int GetServiceCharge()
        public static int GetServiceCharge(int units)
        {
            /*int serviceCharge = 0;
            string sql = "SELECT ServiceCharge FROM OtherFixed WHERE Index=1";
            DataSet dataSet = conn.Show(sql);
            DataTable dt = dataSet.Tables[0];

            foreach (DataRow row in dt.Rows)
            {
                serviceCharge = int.Parse(row[0].ToString());
            }
             
             return serviceCharge;*/

            int serviceCharge = 0;

            List<Range> ranges = GetRanges();

            int ranged_In = 0;

            for (int i = 0; i < ranges.Count; i++)
            {
                if (ranges[i].lower <= units && units <= ranges[i].upper)
                {
                    ranged_In = i;
                    break;
                }
            }

            string sql = "SELECT FixedCharge FROM Charges";
            DataSet dataSet = conn.Show(sql);
            DataTable dt = dataSet.Tables[0];

            serviceCharge = int.Parse(dt.Rows[ranged_In].ItemArray[0].ToString());

            return serviceCharge;
        }
        
        /// <summary>
        /// Get Welfare Charge
        /// </summary>
        /// <returns></returns>
        public static int GetWelfare()
        {
            int welfare = 0;
            string sql = "SELECT Welfare FROM OtherFixed WHERE Index=1";
            DataSet dataSet = conn.Show(sql);
            DataTable dt = dataSet.Tables[0];

            foreach (DataRow row in dt.Rows)
            {
                welfare = int.Parse(row[0].ToString());
            }
            return welfare;
        }

        /// <summary>
        /// Get Units Consumed
        /// </summary>
        /// <param name="pre"></param>
        /// <param name="now"></param>
        /// <returns></returns>
        public static int GetUnitsConsumed(int pre, int now)
        {
            return (now - pre);
        }

        public static double GetCharge(int units)
        {
            List<Range> ranges = GetRanges();
            int ranged_In = 0;

            for (int i = 0; i < ranges.Count; i++)
            {
                if (ranges[i].lower <= units && units <= ranges[i].upper)
                {
                    ranged_In = i + 1;
                    break;
                }
            }

            //Calculate cost
            double cost = 0;
            int remainingUnits = units;
            for (int j = 1; j <= ranged_In; j++)
            {
                if (j != ranged_In)
                {
                    cost += (ranges[j - 1].upper - ranges[j - 1].lower + 1) * ranges[j - 1].charge;
                    remainingUnits -= (ranges[j - 1].upper - ranges[j - 1].lower + 1);
                }
                else if (j == ranged_In)
                {
                    cost += ranges[j - 1].charge * remainingUnits;
                }
            }
            return cost;
        }
        
        public static List<Range> GetRanges()
        {
            List<Range> ranges = new List<Range>();
            string sql = "SELECT * FROM Charges";
            DataSet dataset = conn.Show(sql);
            DataTable dt = dataset.Tables[0];

            foreach (DataRow row in dt.Rows)
            {
                if (row[0].ToString().Contains('-'))
                {
                    string[] range = row[0].ToString().Split('-');
                    ranges.Add(new Range(int.Parse(range[0]), int.Parse(range[1]), double.Parse(row[1].ToString())));
                }
                else
                {
                    string range = row[0].ToString();
                    ranges.Add(new Range(int.Parse(range), 10000, double.Parse(row[1].ToString())));          
                }
            }

            return ranges;
        }
    }
    
    public struct Range
    {
        static int count = 1;
        public int index;
        public int lower;
        public int upper;
        public double charge;

        public Range(int lower, int upper, double charge)
        {
            this.index = count++;
            this.lower = lower;
            this.upper = upper;
            this.charge = charge;
        }
    }
}
